package com.briup.smartcity_group7.service.impl;

import com.briup.smartcity_group7.bean.basic.BaseUser;
import com.briup.smartcity_group7.dao.basic.BaseUserMapper;
import com.briup.smartcity_group7.dao.ext.BaseUserExtMapper;
import com.briup.smartcity_group7.exception.ServiceException;
import com.briup.smartcity_group7.service.IBaseUserService;
import com.briup.smartcity_group7.util.JwtUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import static com.briup.smartcity_group7.status.status_role.role;
import static com.briup.smartcity_group7.status.status_role.status;

/**
 * @Author: lenovo
 * @Date: 2023/01/04/18:23
 */
@Slf4j
@Service //service对象
public class BaseUserServiceImpl implements IBaseUserService {
    @Autowired
    private BaseUserMapper mapper;//逆向工程生成的映射器对象，基本CURD
    @Autowired
    private BaseUserExtMapper extMapper;//扩展映射器CURD

    /**
     * 登录功能具体实现方法
     * @param username 用户名
     * @param password 密码
     * @return 登录信息--token字符串
     */
    @Override
    public String login(String username, String password) {
        //具体实现--创建对象（alt+enter）
        BaseUser baseUser = extMapper.selectByName(username);
        //一系列逻辑判断
        if(baseUser==null){ //1、判断用户名是否存在
            throw new ServiceException("用户名不存在");
        }else if(baseUser.getStatus()!=status) {  //2、判断用户账号状态是否锁定--status!=0锁定
            throw new ServiceException("账号被锁定");
        }else if(!password.equals(baseUser.getPassword())){ //3、判断密码是否正确--与数据库
            throw new ServiceException("密码错误");
        }
        //4、通过以上逻辑判断，则用户通过验证，可以登陆操作，返回jwt字符串
        Map<String,Object> userInfo = new HashMap();
        //储存用户名到浏览器，密码隐藏
        userInfo.put("username",baseUser.getUsername());
        String token = JwtUtil.sign(baseUser.getUsername(), userInfo);
        return token;
    }

    @Override
    public BaseUser currentUserInfo(String token) {
        String username = JwtUtil.getUserId(token);
        return extMapper.selectByName(username);
    }

    @Override
    public PageInfo<BaseUser> findAll(int pageNum, int pageSize) {
        PageInfo<BaseUser> pageInfo = PageHelper.startPage(pageNum, pageSize, true)
                .doSelectPageInfo(() -> extMapper.selectAll());
        return pageInfo;
    }

    @Override
    public void deleteUserById(Integer id) {
        BaseUser baseUser = extMapper.selectById(id);
        if(baseUser==null){ //判断当前用户是否存在
            throw new ServiceException("删除失败，此用户不存在");
        }
        mapper.deleteByPrimaryKey(id);
    }

    //更新用户信息
    @Override
    public void updateUserById(BaseUser baseUser) {
        BaseUser id = mapper.selectByPrimaryKey(baseUser.getUserId());
        if(id==null){
            throw new ServiceException("修改失败，该用户不存在");
        }
        mapper.updateByPrimaryKeySelective(baseUser);
    }

    //更新用户头像
    @Override
    public void updateIconById(Integer userId, String icon) {
        extMapper.updateIcon(userId,icon);
    }
//    public void updateIconById(BaseUser baseUser){
//        mapper.updateByPrimaryKey(baseUser);
//    }

    /**
     * 注册相关操作具体实现
     * @param baseUser 用户信息
     */
    public void addUser(BaseUser baseUser) {
        log.info((baseUser.toString()));
        baseUser.setRegisterTime(new Date()); //邮箱注册时间--提供默认值
        baseUser.setStatus(status); //默认0，正常状态
        baseUser.setRole(role); //默认权限值0--》管理员
        /*
        当注册时，数据必须满足数据库的约束要求：唯一、非空、主键。。。
        so提供一个逻辑判断，使得用户明确知道注册时”程序内部错误“ 具体指的什么问题
        使用user接收当前注册用户的电话号码，对此进行逻辑判断，是否已经存在？
         */
        BaseUser user = extMapper.selectByPhone(baseUser.getTelephone());
        if(user!=null) { //已存在
            throw new ServiceException("注册失败，该手机号已被注册");
        }
        //√补充1：除手机号唯一之外，username、邮箱也可以是唯一标识，添加代码，提示相关信息
        BaseUser userName = extMapper.selectByUserName(baseUser.getUsername());
        if(userName!=null){ //已存在
            throw new ServiceException("注册失败，该用户名已存在");
        }
        BaseUser userEmail = extMapper.selectByEmail(baseUser.getEmail());
        if(userEmail!=null){
            throw new ServiceException("注册失败，该邮箱账号已存在");
        }

        //√补充2：添加密码校验，逻辑判断实现密码安全等级：低--中--高（位数，数字，大小写，符号）
        String userPassword = baseUser.getPassword();
        if(userPassword.length() < 6 ){
            throw new ServiceException("注册失败，密码安全等级过低,至少六位且包含数字、大小写字母");
        }else if(Pattern.compile("[A-Z]").matcher(userPassword).find()==false){
            throw new ServiceException("注册失败，密码安全等级过低,至少六位且包含数字、大小写字母");
        }else if(Pattern.compile("[a-z]").matcher(userPassword).find()==false){
            throw new ServiceException("注册失败，密码安全等级过低,至少六位且包含数字、大小写字母");
        }
        mapper.insert(baseUser);
    }

}
